using System.Configuration;
using System.Xml;
using System.Collections.Generic;
using elmah2.core.interfaces;
using System;
using System.Linq;

namespace elmah2.core.config
{
  public sealed class LoggerSection : IConfigurationSectionHandler
  {
    public List<Logger> Loggers { get; set; }

    public object Create(object parent, object configContext, XmlNode section)
    {
      LoggerSection config = new LoggerSection();
      config.LoadValuesFromXml(section);
      return config;
    }

    private void LoadValuesFromXml(XmlNode section)
    {
      Loggers = new List<Logger>();
      foreach (XmlNode childNode in section.ChildNodes)
      {
        if (childNode.Name.Equals("logger"))
        {
          Loggers.Add(new Logger()
              {
                Config = InitConfigOptions(childNode),
                Type = childNode.Attributes["Type"].Value
              });
        }
      }
    }

    private Dictionary<string, string> InitConfigOptions(XmlNode childNode)
    {
      Dictionary<string, string> toReturn = new Dictionary<string, string>();
      foreach (XmlAttribute xla in childNode.Attributes)
        toReturn.Add(xla.Name, xla.Value);

      return toReturn;
    }
  }

  public sealed class Logger
  {
    public Dictionary<string, string> Config { get; set; }
    public string Type { get; set; }

    private static List<IErrorLogger> _loggers;
    public static List<IErrorLogger> GetLoggers()
    {
      if (_loggers == null)
      {
        _loggers = new List<IErrorLogger>();
        LoggerSection config = (LoggerSection)ConfigurationManager.GetSection("elmah2/loggers");

        if (config == null)
          return null;

        foreach (var v in config.Loggers)
        {
          Type type = System.Type.GetType(v.Type, true);
          IErrorLogger e1 = (IErrorLogger)Activator.CreateInstance(type, new object[] { });
          e1.Init(v.Config);
          _loggers.Add(e1);
        }
      }
      return _loggers;
    }

    public static IErrorLogger GetLogger(string name)
    {
      if (_loggers == null)
        GetLoggers();

      return _loggers.Where(R => R.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault();
    }
  }
}
